package com.ddatsh.transaction.core.provider.impl;


import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.ddatsh.transaction.core.exception.TransException;
import com.ddatsh.transaction.core.model.ApplicationContext;
import com.ddatsh.transaction.core.model.ApplicationErrorCode;
import com.ddatsh.transaction.core.model.TransContext;
import com.ddatsh.transaction.core.model.TransDump;
import com.ddatsh.transaction.core.provider.ExceptionDumpProvider;
import com.ddatsh.transaction.core.provider.JsonConvertProvider;

/**
 * dump服务提供器
 * 当交易执行过程出现异常的时候将，交易相关的数据保存到相关的文件中
 * 
 * @author ddatsh
 * @version 1.0
 */
public class ExceptionDumpProviderImpl implements ExceptionDumpProvider {
	private Logger logger = LoggerFactory.getLogger(ExceptionDumpProviderImpl.class);
	private JsonConvertProvider jsonConvertProvider;

	public void setJsonConvertProvider(JsonConvertProvider jsonConvertProvider) {
		this.jsonConvertProvider = jsonConvertProvider;
	}

	/**
	 * dump方法
	 * 
	 * @param transContext
	 *            交易上下文
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public void dump(TransContext transContext) {
		try {
			String requestNo = transContext.getRequest() == null ? null : transContext.getRequest().getRequestNo();
			String responseNo = transContext.getResponse() == null ? null : transContext.getResponse().getResponseNo();

			String transStatus = transContext.getTransaction().getStatus();
			String appContextJson = jsonConvertProvider.toJson(transContext.getApplicationProperies());
			String exception = null;

			if (transContext.getException() != null) {
				OutputStream outputStream = new ByteArrayOutputStream();
				PrintStream printStream = new PrintStream(outputStream);
				transContext.getException().printStackTrace(printStream);
				exception = outputStream.toString();
			}

			Map<String, String> transInfo = new HashMap<String, String>();
			transInfo.put("requestNo", requestNo);
			transInfo.put("responseNo", responseNo);
			transInfo.put("exception", exception);
			transInfo.put("transStatus", transStatus);

			String transContextJson = jsonConvertProvider.toJson(transInfo);
			TransDump dump = new TransDump();
			dump.setServerIp(ApplicationContext.getServerIp());
			dump.setServerName(ApplicationContext.getServerName());
			dump.setTransContextJson(transContextJson);

			dump.setAppContextJson(appContextJson);
			dump.setTransNo(transContext.getRequest().getRequestNo());
			dump.setDumpTime(new Date());
			//dump内容保存到日志文件中
			logger.debug(jsonConvertProvider.toJson(dump));
		} catch (Exception e) {
			logger.error("dump Transaction Context error！", e);
			throw new TransException(ApplicationErrorCode.EXCEPTION, "dump Transaction Context error！");
		}
	}
}